package net.orange.console.schedule;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Timer;

import net.orange.architecture.process.ProcessFactory;
import net.orange.framework.logic.IJobProcess;
import net.orange.framework.model.Job;

/**
 * System schedule job controller which load or start the schedule job or
 * suspend the job. It will be initialize in startup listener when the system
 * initialization.
 */
public class Schedule {

	/**
	 * Whether is the system schedule is running / open.
	 */
	private static boolean running = false;

	/**
	 * The system schedule jobs collection.
	 */
	private static Map<String, Timer> timers = new HashMap<String, Timer>();

	/**
	 * Disabled the default constructor, it only open the static method.
	 */
	private Schedule() {
		super();
	}

	/**
	 * Start all the schedule jobs.
	 * 
	 * @throws Exception
	 */
	public static void startAll() throws Exception {
		if (running)
			return;

		IJobProcess process = (IJobProcess) ProcessFactory.find(Job.class);
		Collection collection = process.listAllEnabled();

		for (Object job : collection) {
			JobAgent jobAgent = new JobAgent((Job) job);
			Timer timer = new Timer();
			timer.schedule(jobAgent, jobAgent.getStartdate(), jobAgent
					.getInterval_second());
			timers.put(String.valueOf(jobAgent.getPk()), timer);
		}

		running = true;
	}

	/**
	 * Stop all the schedule jobs.
	 * 
	 * @throws Exception
	 */
	public static void stopAll() throws Exception {
		Set set = timers.entrySet();

		while (set.iterator().hasNext()) {
			Timer job = (Timer) set.iterator().next();
			job.cancel();
		}

		timers.clear();
		running = false;
	}

	/**
	 * Start the special job
	 * 
	 * @param job
	 *            The special job
	 * @throws Exception
	 */
	public static void start(Job job) throws Exception {
		if (job == null)
			return;

		// Stop the job first if existed.
		stop(job);

		JobAgent jobAgent = new JobAgent((Job) job);
		Timer timer = new Timer();
		timer.schedule(jobAgent, jobAgent.getStartdate(), jobAgent
				.getInterval_second());
		timers.put(String.valueOf(jobAgent.getPk()), timer);
	}

	/**
	 * Stop the special job
	 * 
	 * @param job
	 *            The special job
	 * @throws Exception
	 */
	public static void stop(Job job) throws Exception {
		if (job == null)
			return;

		Timer timer = timers.get(String.valueOf(job.getPk()));

		if (timer != null) {
			timer.cancel();
			timers.remove(String.valueOf(job.getPk()));
		}
	}

	/**
	 * Check the job is running.
	 * 
	 * @param job
	 * @return
	 */
	public static boolean isRunning(Job job) {
		if (job == null)
			return false;

		Timer timer = timers.get(String.valueOf(job.getPk()));
		return (timer != null);
	}

	/**
	 * @return the running
	 */
	public static boolean isRunning() {
		return running;
	}
}
